<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

namespace App\Services\System\Admin;

use App\Exceptions\AdminException;
use App\Model\Admin\SystemAdminModel;
use App\Services\System\SystemMenusServices;
use EasySwoole\Component\Singleton;
use EasySwoole\EasySwoole\Config;
use EasySwoole\FastCache\Cache;
use App\Services\BaseServices;
use EasySwoole\Jwt\Jwt;
use FormBuilder\Exception\FormBuilderException;
use FormBuilder\Factory\Iview as Form;

/**
 * Description of SystemAdminServices
 *
 * @author zike
 */
class SystemAdminServices  extends BaseServices{

    use Singleton;

    /**
     * 添加管理员form表单获取
     * @param int $level
     * @return array
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function createForm(int $level)
    {
        return create_form('管理员添加', $this->createAdminForm($level), $this->url('/setting/admin'));
    }

    /**
     * 修改管理员表单
     * @param int $level
     * @param int $id
     * @return array
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function updateForm(int $level, int $id)
    {	
	$adminInfo = SystemAdminModel::create()->get($id);
        if (!$adminInfo) {
            throw new AdminException('管理员不存在!');
        }
        if ($adminInfo->is_del) {
            throw new AdminException('管理员已经删除');
        }
	
        return create_form('管理员修改', $this->createAdminForm($level, $adminInfo->toArray()), $this->url('/setting/admin/' . $id), 'PUT');
    }

    /**
     * 创建管理员表单
     * @param int $level
     * @param array $formData
     * @return mixed
     * @throws \FormBuilder\Exception\FormBuilderException
     */
    public function createAdminForm(int $level, array $formData = [])
    {
        $f[] = Form::input('account', '管理员账号', $formData['account'] ?? '')->required('请填写管理员账号');
        $f[] = Form::input('pwd', '管理员密码')->type('password')->required('请填写管理员密码');
        $f[] = Form::input('conf_pwd', '确认密码')->type('password')->required('请输入确认密码');
        $f[] = Form::input('real_name', '管理员姓名', $formData['real_name'] ?? '')->required('请输入管理员姓名');

        /** @var SystemRoleServices $service */
        $options = SystemRoleServices::getInstance()->getRoleFormSelect($level);
        $f[] = Form::select('roles', '管理员身份', $formData['roles'] ?? [])->setOptions($options)->multiple(true)->required('请选择管理员身份');
        $f[] = Form::radio('status', '状态', $formData['status'] ?? 1)->options([['label' => '开启', 'value' => 1], ['label' => '关闭', 'value' => 0]]);
        return $f;
    }

    /**
     * 管理员列表
     * @param array $where
     * @return array
     */
    public function getAdminList(array $where, $level, $page = 1, $limit = 10)
    {
	$model = SystemAdminModel::create()->where('is_del', 0)->where('level', $level);
	if ($where['status'] !== '')
	    $model->where('status', $where['status']);
	if ($where['name'] !== '') {
	    $like = '%' . $where['name'] . '%';
	    $model->where("(account like ? OR real_name like ?)", [$like, $like]);
	}
	$model = $model->limit($limit * ($page - 1), $limit)->withTotalCount();
	$list = $model->all(null); // 列表数据
	$result = $model->lastQueryResult();
	$count = $result->getTotalCount(); // 总条数

        /** @var SystemRoleServices $service */
        $allRole = SystemRoleServices::getInstance()->getRoleArray();
        foreach ($list as &$item) {
	    $item = $item->toArray();
            if ($item['roles']) {
                $roles = [];
                foreach ($item['roles'] as $id) {
                    if (isset($allRole[$id])) $roles[] = $allRole[$id]['role_name'];
                }
                if ($roles) {
                    $item['roles'] = implode(',', $roles);
                } else {
                    $item['roles'] = '';
                }
            }
            $item['_add_time'] = date('Y-m-d H:i:s', $item['add_time']);
            $item['_last_time'] = $item['last_time'] ? date('Y-m-d H:i:s', $item['last_time']) : '';
        }
        return compact('list', 'count');
    }

    /**
     * 管理员登陆
     * @param string $account
     * @param string $password
     * @return array|\think\Model
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function verifyLogin(string $account, string $password) {
	$adminInfo = SystemAdminModel::create()->where(['account' => $account, 'is_del' => 0, 'status' => 1])->get();
	if (!$adminInfo) {
	    throw new AdminException('管理员不存在!');
	}
	if (!$adminInfo->status) {
	    throw new AdminException('您已被禁止登录!');
	}
	if (!password_verify($password, $adminInfo->pwd)) {
	    throw new AdminException('账号或密码错误，请重新输入');
	}

	return $adminInfo;
    }

    /**
     * 后台登陆获取菜单获取token
     * @param string $account
     * @param string $password
     * @param string $type
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function login(string $account, string $password, string $type, string $ip) {
	$adminInfo = $this->verifyLogin($account, $password);
	$adminInfo->last_time = time();
	$adminInfo->last_ip = $ip;
	$adminInfo->login_count++;
	$adminInfo->update();


	// 生成token
	$config = Config::getInstance();
	$jwtConfig = $config->getConf('JWT');

	$jwtObject = Jwt::getInstance()
		->setSecretKey($jwtConfig['key']) // 秘钥
		->publish();

	$jwtObject->setAlg('HMACSHA256'); // 加密方式
	$jwtObject->setAud("easy_swoole_admin"); // 用户
	$jwtObject->setJti(md5($adminInfo->id . ":{$type}:" . time())); // jwt id 用于标识该jwt

	$jwtObject->setExp(time() + $jwtConfig['exp']); // 过期时间
	$jwtObject->setIat(time()); // 发布时间
	$jwtObject->setNbf(time()); // 在此之前不可用

	$jwtObject->setIss($jwtConfig['iss']); // 发行人
	$jwtObject->setSub($jwtConfig['sub']); // 主题
	// 自定义数据
	$exp = $jwtObject->getExp();
	$data = [$adminInfo->id, $type, $exp];
	$jwtObject->setData($data);

	$token = $jwtObject->__toString();
	Cache::getInstance()->set(md5($token), $data, $exp - time() + 60);
	/** @var SystemMenusServices $services */
	[$menus, $uniqueAuth] = SystemMenusServices::getInstance()->getMenusList($adminInfo->roles, (int) $adminInfo['level']);
	return [
	    'token' => $token, // 最终生成的token
	    'expires_time' => $exp,
	    'menus' => $menus,
	    'unique_auth' => $uniqueAuth,
	    'user_info' => [
		'id' => $adminInfo->id,
		'account' => $adminInfo->account,
		'head_pic' => $adminInfo->head_pic,
	    ],
	    'logo' => Config::getInstance()->getConf('site_logo'), //sys_config('site_logo'),
	    'logo_square' => Config::getInstance()->getConf('site_logo_square'), //sys_config('site_logo_square'),
	    'version' => Config::getInstance()->getConf('VERSION'), //get_crmeb_version(),
	    'newOrderAudioLink' => Config::getInstance()->getConf('new_order_audio_link')// get_file_link(sys_config('new_order_audio_link', ''))
	];
    }

}
